package network.server;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

public class RoomsPool {

    private HashMap<String, HashSet<ClientSocket>> rooms;
    private final String defaultRoomName = "default";
    private Object monitor = new Object();

    public RoomsPool(HashMap rooms) {
        this.rooms = rooms;
        rooms.put(defaultRoomName, new HashSet<ClientSocket>());
    }

    public boolean addClientToDefaultRoom(ClientSocket clientSocket) {
        synchronized (rooms) {
            return getRoom(defaultRoomName).add(clientSocket);
        }
    }

    public HashSet<ClientSocket> getRoom(String name) {
        synchronized (monitor) {
            if (!rooms.containsKey(name)) {
                rooms.put(name, new HashSet<>());
            }
            return rooms.get(name);
        }
    }

    public boolean moveClientToAnotherRoom(ClientSocket clientSocket, String oldRoom, String newRoom) throws IOException {
        synchronized (rooms) {
            if (!getRoom(oldRoom).contains(clientSocket)) {
                return false;
            }
            getRoom(oldRoom).remove(clientSocket);
            getRoom(newRoom).add(clientSocket);
            checkRoomFullness(oldRoom);
            return true;
        }
    }

    public boolean checkNameAvailibility(String clientName) {
        synchronized (rooms) {
            for (HashMap.Entry<String, HashSet<ClientSocket>> room : rooms.entrySet()) {
                for (ClientSocket socket : room.getValue()) {
                    if (socket.getLogin().equals(clientName))
                        return false;
                }
            }
        }
        return true;
    }

    public String findRoomByClientName(String clientName) {
        synchronized (rooms) {
            for (HashMap.Entry<String, HashSet<ClientSocket>> room : rooms.entrySet()) {
                for (ClientSocket socket : room.getValue()) {
                    if (socket.getLogin().equals(clientName))
                        return room.getKey();
                }
            }
        }
        return null;
    }

    public ClientSocket findSocketByClientName(String clientName) {
        synchronized (rooms) {
            for (HashMap.Entry<String, HashSet<ClientSocket>> room : rooms.entrySet()) {
                for (ClientSocket socket : room.getValue()) {
                    if (socket.getLogin().equals(clientName)) {
                        return socket;
                    }
                }
            }
        }
        return null;
    }

    public void checkRoomFullness(String roomName) {
        if (getRoom(roomName).isEmpty()) {
            rooms.remove(roomName);
        }
    }

    public boolean removeClientfromPool(ClientSocket clientSocket) throws IOException {
        for (Collection room : rooms.values()) {
            if (room.contains(clientSocket)) {
                clientSocket.close();
                return room.remove(clientSocket);
            }
        }
        return false;
    }
}
